<?php

namespace App\Kuafu\Shop\Model;

use App\Kuafu\Base\Enum\DBEnum;
use App\Kuafu\Base\Model\BaseModel;
use App\Kuafu\Base\Model\Traits\KfSoftDeletes;
use App\Kuafu\Base\Model\Traits\KfUid;
use App\Kuafu\Product\Enum\CodeEnum;
use App\Kuafu\Product\Enum\ProductCodeEnum;
use App\Kuafu\Product\Exceptions\ProductException;
use App\Kuafu\Product\Model\Product;
use App\Kuafu\User\Model\User;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\HigherOrderTapProxy;

class ShopProductStatus extends BaseModel
{
    use HasFactory, KfSoftDeletes, KfUid;

    protected $connection  = 'mysql';
    protected $table       = 'shop_product_status';
    protected $primaryKey  = 'id';
    protected $fillable    = [
        'brandId',
        'shopId',
        'productId',
        'status',
        'out',
        'price',
        'showPlatform',
        'createdByUid',
        'updatedByUid',
        'isDeleted',
        'isMust',
    ];
    protected $modelCached = true;


    public function productRel(): \Illuminate\Database\Eloquent\Relations\HasOne
    {
        return $this->hasOne(Product::class, 'id', 'productId');
    }

    /**
     * 新增/编辑
     * 使用后需要删除Cache
     * @param int $brandId
     * @param int $shopId
     * @param int $productId
     * @param int $price
     * @param int $showPlatform
     * @param int|null $status
     * @param int|null $out
     * @return bool
     */
    public static function addData(
        int $brandId,
        int $shopId,
        int $productId,
        int $price,
        int $showPlatform,
        ?int $status,
        ?int $out
    ): bool {
        $map = [
            'brandId'   => $brandId,
            'shopId'    => $shopId,
            'productId' => $productId,
        ];
        $c   = self::customFirstOrCreate(
            $map,
            array_merge(
                $map,
                [
                    "price"        => $price,
                    "showPlatform" => $showPlatform
                ]
            )
        );
        if ($status !== null) {
            $c->status = $status;
        }

        if ($out !== null) {
            $c->out = $out;
        }

        return $c->save();
    }

    /**
     * @param int $shopId
     * @param int $brandId
     * @param int $productId
     * @param int $price
     * @param int $showPlatform
     * @param int $status
     * @return Builder|Model|HigherOrderTapProxy|mixed|object|null
     */
    public static function insertOrGet(
        int $shopId,
        int $brandId,
        int $productId,
        int $price,
        int $showPlatform,
        int $status = DBEnum::STATUS_ON
    ) {
        return self::customFirstOrCreate(
            [
                "brandId"   => $brandId,
                "shopId"    => $shopId,
                "productId" => $productId
            ],
            [
                "status"       => $status,
                "price"        => $price,
                "showPlatform" => $showPlatform
            ]
        );
    }

    /**
     * 查询下架/估清列表
     * 缓存方法：ShopService::sGetStatusList
     * @param int $brandId
     * @param int $shopId
     * @param array $productIds
     * @return Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public static function getStatusList(int $shopId, array $productIds = [])
    {
        return self::query()
                   ->where('shopId', $shopId)
//            ->where('brandId', $brandId)
                   ->where(function ($q) {
                $q->where('status', DBEnum::STATUS_DOWN)
                  ->orWhere('out', DBEnum::STATUS_DOWN);
            })
                   ->when($productIds, function ($q) use ($productIds) {
                       return $q->whereIn('productId', $productIds);
                   })
                   ->select('productId', 'status', 'out')
                   ->get();
    }

    /**
     * 查询下架/估清列表
     * 缓存方法：ShopService::sGetStatusList
     * @param int $brandId
     * @param int $shopId
     * @param array $productIds
     * @return Builder[]|\Illuminate\Database\Eloquent\Collection
     */


    /**
     * 查询定制菜品列表
     *
     * @param int $shopId
     * @param array $productIds
     * @return array|Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public static function getCustomProductList(int $shopId, array $productIds = [])
    {
        return self::query()
                   ->where('shopId', $shopId)
                   ->when($productIds, function ($q) use ($productIds) {
                       return $q->whereIn('productId', $productIds);
                   })
                   ->get();
    }

    /**
     * @param int $shopId
     * @param int $brandId
     * @return int
     */
    public static function getShopCustomProductOnlineNum(int $shopId, int $brandId): int
    {
        return Product::query()
                      ->where("kind", CodeEnum::KIND_CUSTOMER)
                      ->whereHas("productStatusRel", function ($query) use ($shopId, $brandId) {
                          $query->where("shopId", $shopId)
                                ->where("brandId", $brandId)
                                ->where("status", DBEnum::STATUS_ON)
                                ->where("isDeleted", 0);
                      })
                      ->where("status", DBEnum::STATUS_ON)
                      ->where("isDeleted", 0)
                      ->count();
    }

    /**
     * @param int $shopId
     * @param int $brandId
     * @param int $productId
     * @param int $price
     * @param int $showPlatform
     * @param int $status
     * @throws ProductException
     */
    public static function status(
        int $shopId,
        int $brandId,
        int $productId,
        int $price,
        int $showPlatform,
        int $status
    ) {
        $map               = [
            "brandId"   => $brandId,
            "shopId"    => $shopId,
            "productId" => $productId
        ];
        $shopProductStatus = self::query()->where($map)->first();

        if (empty($shopProductStatus)) {
            tap(static::query()->newModelInstance(
                array_merge($map, [
                    "status"       => $status,
                    "price"        => $price,
                    "showPlatform" => $showPlatform
                ])
            ), function ($instance) {
                $instance->save();
            });
        } else {
            if ($status == $shopProductStatus->status) {
                throw new ProductException(ProductCodeEnum::ERR_PRODUCT_STATUS_SET);
            }
            $shopProductStatus->update(["status" => $status]);
        }
    }

    /**
     * 删除菜品
     *
     * @param int $shopId
     * @param int $brandId
     * @param int $productId
     * @param int $price
     * @param int $showPlatform
     * @param int $status
     * @throws ProductException
     */
    public static function del(
        int $shopId,
        int $brandId,
        int $productId,
        int $price,
        int $showPlatform,
        int $status
    ) {
        $map               = [
            "brandId"   => $brandId,
            "shopId"    => $shopId,
            "productId" => $productId
        ];
        $shopProductStatus = self::query()->withoutGlobalScope("isDel")->where($map)->first();

        if (empty($shopProductStatus)) {
            tap(static::query()->newModelInstance(
                array_merge($map, [
                    "isDeleted"    => 1,
                    "status"       => $status,
                    "price"        => $price,
                    "showPlatform" => $showPlatform
                ])
            ), function ($instance) {
                $instance->save();
            });
        } else {
            if ($shopProductStatus->status == DBEnum::STATUS_ON) {
                throw new ProductException(ProductCodeEnum::ERR_PRODUCT_DEL_AFTER_OFFLINE);
            }

            $shopProductStatus->update(["isDeleted" => 1]);
        }
    }
}
